<?php

namespace app\common\library;

use think\Config;
use think\Exception;

/**
 * 千牛API服务类
 */
class QianniuApi
{
    private $config;
    private $baseUrl;
    private $timeout;
    
    public function __construct()
    {
        $this->config = Config::get('qianniu');
        $this->baseUrl = $this->config['api']['base_url'];
        $this->timeout = $this->config['api']['timeout'];
    }
    
    /**
     * 获取千牛用户信息
     */
    public function getUserInfo($code, $corpId)
    {
        $params = [
            'app_key' => $this->config['app_key'],
            'app_secret' => $this->config['app_secret'],
            'corp_id' => $corpId,
            'code' => $code
        ];
        
        $url = $this->baseUrl . '/user/info';
        $result = $this->httpGet($url, $params);
        
        if (!$result) {
            throw new Exception('获取千牛用户信息失败');
        }
        
        $data = json_decode($result, true);
        if (isset($data['errcode']) && $data['errcode'] != 0) {
            throw new Exception('千牛API错误：' . ($data['errmsg'] ?? '未知错误'));
        }
        
        return $data['data'] ?? [];
    }
    
    /**
     * 获取千牛组织信息
     */
    public function getOrganizations($corpId, $accessToken = '')
    {
        $params = [
            'app_key' => $this->config['app_key'],
            'corp_id' => $corpId
        ];
        
        if ($accessToken) {
            $params['access_token'] = $accessToken;
        }
        
        $url = $this->baseUrl . '/organization/list';
        $result = $this->httpGet($url, $params);
        
        if (!$result) {
            throw new Exception('获取千牛组织信息失败');
        }
        
        $data = json_decode($result, true);
        if (isset($data['errcode']) && $data['errcode'] != 0) {
            throw new Exception('千牛API错误：' . ($data['errmsg'] ?? '未知错误'));
        }
        
        return $data['data'] ?? [];
    }
    
    /**
     * 获取千牛部门成员
     */
    public function getDepartmentMembers($corpId, $deptId, $accessToken = '')
    {
        $params = [
            'app_key' => $this->config['app_key'],
            'corp_id' => $corpId,
            'dept_id' => $deptId
        ];
        
        if ($accessToken) {
            $params['access_token'] = $accessToken;
        }
        
        $url = $this->baseUrl . '/department/members';
        $result = $this->httpGet($url, $params);
        
        if (!$result) {
            throw new Exception('获取千牛部门成员失败');
        }
        
        $data = json_decode($result, true);
        if (isset($data['errcode']) && $data['errcode'] != 0) {
            throw new Exception('千牛API错误：' . ($data['errmsg'] ?? '未知错误'));
        }
        
        return $data['data'] ?? [];
    }
    
    /**
     * 发送千牛消息
     */
    public function sendMessage($corpId, $userId, $message, $accessToken = '')
    {
        $params = [
            'app_key' => $this->config['app_key'],
            'corp_id' => $corpId,
            'user_id' => $userId,
            'message' => $message
        ];
        
        if ($accessToken) {
            $params['access_token'] = $accessToken;
        }
        
        $url = $this->baseUrl . '/message/send';
        $result = $this->httpPost($url, $params);
        
        if (!$result) {
            throw new Exception('发送千牛消息失败');
        }
        
        $data = json_decode($result, true);
        if (isset($data['errcode']) && $data['errcode'] != 0) {
            throw new Exception('千牛API错误：' . ($data['errmsg'] ?? '未知错误'));
        }
        
        return $data['data'] ?? [];
    }
    
    /**
     * 获取千牛访问令牌
     */
    public function getAccessToken($corpId)
    {
        $params = [
            'app_key' => $this->config['app_key'],
            'app_secret' => $this->config['app_secret'],
            'corp_id' => $corpId
        ];
        
        $url = $this->baseUrl . '/auth/token';
        $result = $this->httpGet($url, $params);
        
        if (!$result) {
            throw new Exception('获取千牛访问令牌失败');
        }
        
        $data = json_decode($result, true);
        if (isset($data['errcode']) && $data['errcode'] != 0) {
            throw new Exception('千牛API错误：' . ($data['errmsg'] ?? '未知错误'));
        }
        
        return $data['data']['access_token'] ?? '';
    }
    
    /**
     * HTTP GET请求
     */
    private function httpGet($url, $params = [])
    {
        if (!empty($params)) {
            $url .= '?' . http_build_query($params);
        }
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_USERAGENT, 'QianniuApi/1.0');
        
        $result = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception('CURL错误：' . $error);
        }
        
        return $result;
    }
    
    /**
     * HTTP POST请求
     */
    private function httpPost($url, $params = [])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_USERAGENT, 'QianniuApi/1.0');
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded'
        ]);
        
        $result = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception('CURL错误：' . $error);
        }
        
        return $result;
    }
    
    /**
     * 模拟千牛API返回数据（用于开发测试）
     */
    public function getMockUserInfo($code, $corpId)
    {
        return [
            'userid' => 'qianniu_' . substr(md5($code), 0, 8),
            'name' => '千牛用户' . substr(md5($code), 0, 4),
            'avatar' => '',
            'mobile' => '138' . rand(10000000, 99999999),
            'email' => 'user' . rand(1000, 9999) . '@example.com',
            'department_ids' => [rand(1, 5), rand(6, 10)],
            'position' => ['员工', '主管', '经理'][rand(0, 2)],
            'job_number' => 'QN' . date('Ymd') . rand(1000, 9999),
            'status' => 1
        ];
    }
    
    /**
     * 模拟千牛组织数据
     */
    public function getMockOrganizations($corpId)
    {
        return [
            [
                'dept_id' => 1,
                'dept_name' => '生产部',
                'parent_id' => 0,
                'level' => 1
            ],
            [
                'dept_id' => 2,
                'dept_name' => '质检部',
                'parent_id' => 0,
                'level' => 1
            ],
            [
                'dept_id' => 3,
                'dept_name' => '包装部',
                'parent_id' => 0,
                'level' => 1
            ],
            [
                'dept_id' => 4,
                'dept_name' => '生产一组',
                'parent_id' => 1,
                'level' => 2
            ],
            [
                'dept_id' => 5,
                'dept_name' => '生产二组',
                'parent_id' => 1,
                'level' => 2
            ]
        ];
    }
    
    /**
     * 模拟千牛部门成员数据
     */
    public function getMockDepartmentMembers($corpId, $deptId)
    {
        $members = [];
        $count = rand(5, 15);
        
        for ($i = 1; $i <= $count; $i++) {
            $members[] = [
                'userid' => 'user_' . $deptId . '_' . $i,
                'name' => '员工' . $i,
                'avatar' => '',
                'mobile' => '138' . rand(10000000, 99999999),
                'email' => 'user' . $i . '@example.com',
                'position' => ['员工', '组长', '主管'][rand(0, 2)],
                'job_number' => 'QN' . $deptId . str_pad($i, 4, '0', STR_PAD_LEFT),
                'status' => 1
            ];
        }
        
        return $members;
    }
}
